<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=777674
-->
<head>
  <meta charset="utf-8">
  <title>Test for Bug 777674</title>

  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
  <script type="application/javascript;version=1.8" src="inspector-helpers.js"></script>
  <script type="application/javascript;version=1.8">
window.onload = function() {
  const {InspectorFront} =
    require("devtools/shared/fronts/inspector");
  const {_documentWalker} =
    require("devtools/server/actors/inspector");
  const nodeFilterConstants =
    require("devtools/shared/dom-node-filter-constants");
  const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";

  SpecialPowers.pushPrefEnv({"set": [
    ["dom.webcomponents.enabled", true]
  ]});
  SimpleTest.waitForExplicitFinish();

  let gWalker = null;
  let gClient = null;

  addTest(function setup() {
    info ("Setting up inspector and walker actors.");

    let url = document.getElementById("inspectorContent").href;
    attachURL(url, function(err, client, tab, doc) {
      gInspectee = doc;
      let inspector = InspectorFront(client, tab);
      promiseDone(inspector.getWalker().then(walker => {
        ok(walker, "getWalker() should return an actor.");
        gClient = client;
        gWalker = walker;
      }).then(runNextTest));
    });
  });

  addAsyncTest(function* testXBLAnonymousInHTMLDocument() {
    info ("Testing XBL anonymous in an HTML document.");
    let rawToolbarbutton = gInspectee.createElementNS(XUL_NS, "toolbarbutton");
    gInspectee.documentElement.appendChild(rawToolbarbutton);

    let toolbarbutton = yield gWalker.querySelector(gWalker.rootNode, "toolbarbutton");
    let children = yield gWalker.children(toolbarbutton);

    is (toolbarbutton.numChildren, 0, "XBL content is not visible in HTML doc");
    is (children.nodes.length, 0, "XBL content is not returned in HTML doc");

    runNextTest();
  });

  addAsyncTest(function* testNativeAnonymous() {
    info ("Testing native anonymous content with walker.");

    let select = yield gWalker.querySelector(gWalker.rootNode, "select");
    let children = yield gWalker.children(select);

    is (select.numChildren, 2, "No native anon content for form control");
    is (children.nodes.length, 2, "No native anon content for form control");

    runNextTest();
  });

  addAsyncTest(function* testNativeAnonymousStartingNode() {
    info ("Tests attaching an element that a walker can't see.");

    let serverWalker = DebuggerServer._searchAllConnectionsForActor(gWalker.actorID);
    let docwalker = new _documentWalker(
      gInspectee.querySelector("select"),
      gInspectee.defaultView,
      nodeFilterConstants.SHOW_ALL,
      () => {
        return nodeFilterConstants.FILTER_ACCEPT
      }
    );
    let scrollbar = docwalker.lastChild();
    is (scrollbar.tagName, "scrollbar", "An anonymous child has been fetched");

    let node = yield serverWalker.attachElement(scrollbar);

    ok (node, "A response has arrived");
    ok (node.node, "A node is in the response");
    is (node.node.rawNode.tagName, "SELECT",
      "The node has changed to a parent that the walker recognizes");

    runNextTest();
  });

  addAsyncTest(function* testPseudoElements() {
    info ("Testing pseudo elements with walker.");

    // Markup looks like: <div><::before /><span /><::after /></div>
    let pseudo = yield gWalker.querySelector(gWalker.rootNode, "#pseudo");
    let children = yield gWalker.children(pseudo);

    is (pseudo.numChildren, 1, "::before/::after are not counted if there is a child");
    is (children.nodes.length, 3, "Correct number of children");

    let before = children.nodes[0];
    ok (before.isAnonymous, "Child is anonymous");
    ok (!before._form.isXBLAnonymous, "Child is not XBL anonymous");
    ok (!before._form.isShadowAnonymous, "Child is not shadow anonymous");
    ok (before._form.isNativeAnonymous, "Child is native anonymous");

    let span = children.nodes[1];
    ok (!span.isAnonymous, "Child is not anonymous");

    let after = children.nodes[2];
    ok (after.isAnonymous, "Child is anonymous");
    ok (!after._form.isXBLAnonymous, "Child is not XBL anonymous");
    ok (!after._form.isShadowAnonymous, "Child is not shadow anonymous");
    ok (after._form.isNativeAnonymous, "Child is native anonymous");

    runNextTest();
  });

  addAsyncTest(function* testEmptyWithPseudo() {
    info ("Testing elements with no childrent, except for pseudos.");

    info ("Checking an element whose only child is a pseudo element");
    let pseudo = yield gWalker.querySelector(gWalker.rootNode, "#pseudo-empty");
    let children = yield gWalker.children(pseudo);

    is (pseudo.numChildren, 1, "::before/::after are is counted if there are no other children");
    is (children.nodes.length, 1, "Correct number of children");

    let before = children.nodes[0];
    ok (before.isAnonymous, "Child is anonymous");
    ok (!before._form.isXBLAnonymous, "Child is not XBL anonymous");
    ok (!before._form.isShadowAnonymous, "Child is not shadow anonymous");
    ok (before._form.isNativeAnonymous, "Child is native anonymous");

    runNextTest();
  });

  addAsyncTest(function* testShadowAnonymous() {
    info ("Testing shadow DOM content.");

    let shadow = yield gWalker.querySelector(gWalker.rootNode, "#shadow");
    let children = yield gWalker.children(shadow);

    is (shadow.numChildren, 3, "Children of the shadow root are counted");
    is (children.nodes.length, 3, "Children returned from walker");

    let before = children.nodes[0];
    ok (before.isAnonymous, "Child is anonymous");
    ok (!before._form.isXBLAnonymous, "Child is not XBL anonymous");
    ok (!before._form.isShadowAnonymous, "Child is not shadow anonymous");
    ok (before._form.isNativeAnonymous, "Child is native anonymous");

    // <h3>Shadow <em>DOM</em></h3>
    let shadowChild1 = children.nodes[1];
    ok (shadowChild1.isAnonymous, "Child is anonymous");
    ok (!shadowChild1._form.isXBLAnonymous, "Child is not XBL anonymous");
    ok (shadowChild1._form.isShadowAnonymous, "Child is shadow anonymous");
    ok (!shadowChild1._form.isNativeAnonymous, "Child is not native anonymous");

    let shadowSubChildren = yield gWalker.children(children.nodes[1]);
    is (shadowChild1.numChildren, 2, "Subchildren of the shadow root are counted");
    is (shadowSubChildren.nodes.length, 2, "Subchildren are returned from walker");

    // <em>DOM</em>
    let shadowSubChild = children.nodes[1];
    ok (shadowSubChild.isAnonymous, "Child is anonymous");
    ok (!shadowSubChild._form.isXBLAnonymous, "Child is not XBL anonymous");
    ok (shadowSubChild._form.isShadowAnonymous, "Child is shadow anonymous");
    ok (!shadowSubChild._form.isNativeAnonymous, "Child is not native anonymous");

    // <select multiple></select>
    let shadowChild2 = children.nodes[2];
    ok (shadowChild2.isAnonymous, "Child is anonymous");
    ok (!shadowChild2._form.isXBLAnonymous, "Child is not XBL anonymous");
    ok (shadowChild2._form.isShadowAnonymous, "Child is shadow anonymous");
    ok (!shadowChild2._form.isNativeAnonymous, "Child is not native anonymous");

    runNextTest();
  });

  runNextTest();
};
  </script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a>
<a id="inspectorContent" target="_blank" href="inspector-traversal-data.html">Test Document</a>
<p id="display"></p>
<div id="content" style="display: none">

</div>
<pre id="test">
</pre>
</body>
</html>
